#include "syntax.h"

const char *terminal_symbol[TERMINAL_SYMBOL_NUM] = {"$", "IDN", "INT", "FLOAT", "const",
                                                    "int", "float", "if", "else", "void",
                                                    "return", ";", ",", "=", "(",
                                                    ")", "{", "}", "+", "-",
                                                    "!", "*", "/", "%", "<",
                                                    ">", "<=", ">=", "==", "!=",
                                                    "&&", "||"};
const char *non_terminal_symbol[NON_TERMINAL_SYMBOL_NUM] = {"Program", "compUnit", "decl", "constDecl", "multiConstDef",
                                                            "bType", "constDef", "constInitVal", "varDecl", "multiVarDecl",
                                                            "varDef", "initVal", "funcDef", "funcType", "funcFParams",
                                                            "funcFParam", "multiFuncFParam", "block", "blockItem", "stmt",
                                                            "exp", "cond", "lVal", "primaryExp", "number",
                                                            "unaryExp", "unaryOp", "funcRParams", "funcRParam", "multiFuncRParam",
                                                            "mulExp", "temMulExp", "addExp", "temAddExp", "relExp",
                                                            "temRelExp", "eqExp", "temEqExp", "lAndExp", "temLAndExp",
                                                            "lOrExp", "temLOrExp", "constExp"};

const char *start_symbol = "Program";
const char *expand_start_symbol = "myStart";

int get_item_info(item_info *cur_item, string line)
{
    istringstream iss(line);
    string word;
    iss >> word;
    cur_item->point_pos = stoi(word);
    iss >> word;
    cur_item->right_num = stoi(word);
    iss >> word;
    cur_item->left = stoi(word);
    for (int i = 0; i < cur_item->right_num; i++)
    {
        iss >> word;
        cur_item->right[i] = stoi(word);
    }
    return 0;
}

bool is_in_family(vector<int> family, int length, int x)
{
    for (int i = 0; i < length; i++)
    {
        if (family[i] == x)
        {
            return true;
        }
    }
    return false;
}

int is_in_family_x(vector<vector<int>> family, int length, int x)
{
    for (int i = 0; i < length; i++)
    {
        if (is_in_family(family[i], family[i].size(), x))
        {
            return i;
        }
    }
    return -1;
}

bool is_in_edges(vector<item_family_edge> edges, int f, int t, int s)
{
    for (int i = 0; i < edges.size(); i++)
    {
        if (edges[i].from == f && edges[i].to == t && edges[i].symbol == s)
        {
            return true;
        }
    }
    return false;
}

int find_in_symbol(string word)
{
    for (int i = 0; i < TERMINAL_SYMBOL_NUM; i++)
    {
        if (word == terminal_symbol[i])
        {
            return i + 1;
        }
    }
    for (int i = 0; i < NON_TERMINAL_SYMBOL_NUM; i++)
    {
        if (word == non_terminal_symbol[i])
        {
            return i + TERMINAL_SYMBOL_NUM + 1;
        }
    }
    return 0;
}

void debug_print_item(item_info item, int ptr, ofstream &out_file)
{
    out_file << ptr << ": ";
    if (!item.left)
    {
        if (item.point_pos)
        {
            out_file << expand_start_symbol << " -> " << start_symbol << " (#)\n";
        }
        else
        {
            out_file << expand_start_symbol << " -> (#) " << start_symbol << "\n";
        }
        return;
    }
    out_file << non_terminal_symbol[item.left - 1 - TERMINAL_SYMBOL_NUM] << " ->";
    for (int i = 0; i < item.right_num; i++)
    {
        if (item.point_pos == i)
        {
            out_file << " (#)";
        }
        if (item.right[i] < TERMINAL_SYMBOL_NUM)
        {
            out_file << " " << terminal_symbol[item.right[i] - 1];
        }
        else
        {
            out_file << " " << non_terminal_symbol[item.right[i] - 1 - TERMINAL_SYMBOL_NUM];
        }
    }
    if (item.point_pos == item.right_num)
    {
        out_file << " (#)";
    }
    out_file << "\n";
    return;
}

void debug_print_family(item_info my_item[], vector<vector<int>> family_member, int family_i, bool print_all, ofstream &out_file)
{
    if (!print_all)
    {
        if (family_i >= family_member.size())
        {
            perror("Error! edge print out of edge.\n");
        }
        out_file << "family" << family_i << ":\n";
        for (int j = 0; j < family_member[family_i].size(); j++)
        {
            debug_print_item(my_item[family_member[family_i][j]], family_member[family_i][j], out_file);
        }
        out_file << "\n";
        return;
    }
    for (int i = 0; i < family_member.size(); i++)
    {
        out_file << "family" << i << ":\n";
        for (int j = 0; j < family_member[i].size(); j++)
        {
            debug_print_item(my_item[family_member[i][j]], family_member[i][j], out_file);
        }
        out_file << "\n";
    }
    return;
}
void debug_print_edge(vector<item_family_edge> edges, int edge_i, bool print_all, ofstream &out_file)
{
    if (print_all)
    {
        for (int i = 0; i < edges.size(); i++)
        {
            out_file << "edge" << i << ": ";
            out_file << edges[i].from << " -> " << edges[i].to << " symbol: ";
            if (edges[i].symbol <= TERMINAL_SYMBOL_NUM)
            {
                out_file << terminal_symbol[edges[i].symbol - 1];
            }
            else
            {
                out_file << non_terminal_symbol[edges[i].symbol - 1 - TERMINAL_SYMBOL_NUM];
            }
            out_file << "\n";
        }
    }
    else
    {
        if (edge_i >= edges.size())
        {
            perror("Error! edge print out of edge.\n");
        }
        out_file << "edge" << edge_i << ": ";
        out_file << edges[edge_i].from << " -> " << edges[edge_i].to << " symbol: ";
        if (edges[edge_i].symbol <= TERMINAL_SYMBOL_NUM)
        {
            out_file << terminal_symbol[edges[edge_i].symbol - 1];
        }
        else
        {
            out_file << non_terminal_symbol[edges[edge_i].symbol - 1 - TERMINAL_SYMBOL_NUM];
        }
        out_file << "\n";
    }
    return;
}

void debug_print_syntax_analyze(Stack *state_stack, Stack *symbol_stack, string cur_word, ofstream &out_file)
{
    out_file << "State stack: ";
    state_stack->print_all(out_file);
    out_file << "\t\t\tSymbol stack: ";
    symbol_stack->print_all(out_file);
    out_file << "\t\t\tnext word: " << cur_word << "\t\t\t";
    return;
}

void init_state_table(int state_table[][TERMINAL_SYMBOL_NUM + NON_TERMINAL_SYMBOL_NUM + 1], int s_x)
{
    for (int i = 0; i < s_x; i++)
    {
        for (int j = 0; j < TERMINAL_SYMBOL_NUM + NON_TERMINAL_SYMBOL_NUM + 1; j++)
        {
            state_table[i][j] = INIT;
        }
    }
}

void init_set(bool first[][TERMINAL_SYMBOL_NUM + 1], bool follow[][TERMINAL_SYMBOL_NUM + 1])
{
    for (int i = 0; i < NON_TERMINAL_SYMBOL_NUM; i++)
    {
        for (int j = 0; j < TERMINAL_SYMBOL_NUM + 1; j++)
        {
            first[i][j] = false;
            follow[i][j] = false;
        }
    }
    return;
}

int get_FOLLOW(bool first[][TERMINAL_SYMBOL_NUM + 1], bool follow[][TERMINAL_SYMBOL_NUM + 1], item_info my_item[], int item_num)
{
    ofstream debug_first_file("./debug/debug_first_follow.txt");
    if (!debug_first_file.is_open())
    {
        perror("Create debug first file error!");
    }
    for (int i = 0; i < item_num; i++)
    {
        if (my_item[i].point_pos)
        {
            continue;
        }
        if (!my_item[i].right_num) // 产生式右侧为空符号
        {
            first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][1] = true;
        }
        else if (my_item[i].right[0] < TERMINAL_SYMBOL_NUM + 1)
        {
            // $索引为1
            first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][my_item[i].right[0]] = true;
        }
    }
    bool need_while = true;
    while (need_while)
    {
        need_while = false;
        for (int i = 2; i < item_num; i++)
        {
            if (my_item[i].point_pos || !my_item[i].right_num) // 重复，跳过
            {
                continue;
            }
            if (my_item[i].right_num && my_item[i].right[0] >= TERMINAL_SYMBOL_NUM + 1 && my_item[i].left) // 第一个符号为非终结符
            {
                for (int j = 2; j < TERMINAL_SYMBOL_NUM + 1; j++)
                {
                    if (first[my_item[i].right[0] - TERMINAL_SYMBOL_NUM - 1][j] && !first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][j])
                    {
                        first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][j] = true;
                        need_while = true;
                    }
                }
            }
            for (int j = 0; j < my_item[i].right_num; j++)
            {
                if (j == (my_item[i].right_num - 1) && my_item[i].right[j] > TERMINAL_SYMBOL_NUM && first[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][1] && !first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][1])
                // 产生式右侧FIRST集都有$
                {
                    first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][1] = true;
                    need_while = true;
                    break;
                }
                if (my_item[i].right[j] < TERMINAL_SYMBOL_NUM + 1)
                {
                    if (!first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][my_item[i].right[j]])
                    {
                        first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][my_item[i].right[j]] = true;
                        need_while = true;
                    }
                    break;
                }
                if (first[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][1])
                {
                    for (int k = 2; k < TERMINAL_SYMBOL_NUM + 1; k++)
                    {
                        if (first[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][k] && !first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][k])
                        {
                            first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][k] = true;
                            need_while = true;
                        }
                    }
                    continue;
                }
                else
                {
                    for (int k = 2; k < TERMINAL_SYMBOL_NUM + 1; k++)
                    {
                        if (first[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][k] && !first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][k])
                        {
                            first[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][k] = true;
                            need_while = true;
                        }
                    }
                    break;
                }
            }
        }
    }
    for (int i = 0; i < NON_TERMINAL_SYMBOL_NUM; i++)
    {
        debug_first_file << non_terminal_symbol[i] << "\t";
        for (int j = 0; j < TERMINAL_SYMBOL_NUM + 1; j++)
        {
            if (first[i][j])
            {
                if (!j)
                {
                    debug_first_file << "#\t";
                }
                else
                {
                    debug_first_file << terminal_symbol[j - 1] << "\t";
                }
            }
        }
        debug_first_file << "\n";
    }
    debug_first_file << "\n";
    // 以上将FIRST集求完

    follow[0][0] = true;
    need_while = true;
    while (need_while)
    {
        need_while = false;

        for (int i = 2; i < item_num; i++)
        {
            if (my_item[i].point_pos || !my_item[i].right_num) // 重复，跳过
            {
                continue;
            }
            if (my_item[i].right[my_item[i].right_num - 1] > TERMINAL_SYMBOL_NUM) // 右侧最后的符号非终
            {
                for (int k = 0; k < TERMINAL_SYMBOL_NUM + 1; k++)
                {
                    if (k!= 1 && follow[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][k] && !follow[my_item[i].right[my_item[i].right_num - 1] - TERMINAL_SYMBOL_NUM - 1][k])
                    {
                        follow[my_item[i].right[my_item[i].right_num - 1] - TERMINAL_SYMBOL_NUM - 1][k] = true;
                        need_while = true;
                    }
                }
            }

            for (int j = 0; j < my_item[i].right_num - 1; j++) // 当前产生式右侧第j个符号
            {
                if (my_item[i].right[j] > TERMINAL_SYMBOL_NUM) // j字符非终
                {
                    for (int j_i = j + 1; j_i < my_item[i].right_num; j_i++)
                    {
                        if (my_item[i].right[j_i] > TERMINAL_SYMBOL_NUM)
                        {
                            if (first[my_item[i].right[j_i] - TERMINAL_SYMBOL_NUM - 1][1])
                            {

                                for (int j_k = 0; j_k < TERMINAL_SYMBOL_NUM + 1; j_k++)
                                {
                                    if (j_k!=1 && first[my_item[i].right[j_i] - TERMINAL_SYMBOL_NUM - 1][j_k] && !follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][j_k])
                                    {
                                        follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][j_k] = true;
                                        need_while = true;
                                    }
                                }
                                continue;
                            }
                            else
                            {
                                for (int j_k = 0; j_k < TERMINAL_SYMBOL_NUM + 1; j_k++)
                                {
                                    if (j_k!=1 && first[my_item[i].right[j_i] - TERMINAL_SYMBOL_NUM - 1][j_k] && !follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][j_k])
                                    {
                                        follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][j_k] = true;
                                        need_while = true;
                                    }
                                }
                                break;
                            }
                        }
                        else
                        {
                            if (!follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][my_item[i].right[j_i]])
                            {
                                follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][my_item[i].right[j_i]] = true;
                                need_while = true;
                            }
                            break;
                        }
                    }
                }
            }
            for (int j = my_item[i].right_num - 1; j >= 0; j--) // j从右侧最后开始向前
            {
                if (my_item[i].right[j] < TERMINAL_SYMBOL_NUM + 1) // 为终结符
                {
                    break;
                }
                if (first[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][1]) // 此非终结符first集含$
                {
                    for (int k = 0; k < TERMINAL_SYMBOL_NUM + 1; k++)
                    {
                        if (k != 1 && my_item[i].left && follow[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][k] && !follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][k])
                        {
                            follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][k] = true;
                            need_while = true;
                        }
                    }
                    continue;
                }
                else
                {
                    for (int k = 0; k < TERMINAL_SYMBOL_NUM + 1; k++)
                    {
                        if ( k!=1 && my_item[i].left && follow[my_item[i].left - TERMINAL_SYMBOL_NUM - 1][k] && !follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][k])
                        {
                            follow[my_item[i].right[j] - TERMINAL_SYMBOL_NUM - 1][k] = true;
                            need_while = true;
                        }
                    }
                    break;
                }
            }
        }
    }

    for (int i = 0; i < NON_TERMINAL_SYMBOL_NUM; i++)
    {
        debug_first_file << non_terminal_symbol[i] << "\t";
        for (int j = 0; j < TERMINAL_SYMBOL_NUM + 1; j++)
        {
            if (follow[i][j])
            {
                if (!j)
                {
                    debug_first_file << "#\t";
                }
                else
                {
                    debug_first_file << terminal_symbol[j - 1] << "\t";
                }
            }
        }
        debug_first_file << " \n";
    }
    debug_first_file.close();
    return 0;
}

int get_item(char *in_file, const char *start_symbol, const char *expand_start_symbol)
{
    ifstream grammar_file(in_file);
    ofstream item_file("./inter_txt/item.txt");
    if (!grammar_file.is_open())
    {
        perror("Open grammar file error!");
    }
    if (!item_file.is_open())
    {
        perror("Create item file error!");
    }

    // item.txt中每一行：点的位置 右侧符号个数 左侧符号 右侧符号依次排列
    item_file << "0 1 0 " << TERMINAL_SYMBOL_NUM + 1 << "\n";
    item_file << "1 1 0 " << TERMINAL_SYMBOL_NUM + 1 << "\n";
    string line;
    int word_count = 0;
    int item_num = 2;
    while (getline(grammar_file, line))
    {
        istringstream iss(line);
        string word;
        string first_word;
        word_count = -2; // 将前面的序号去掉
        while (iss >> word)
        {
            word_count++;
            if (word_count == 2)
            {
                first_word = word;
            }
        }
        if (first_word == terminal_symbol[0] && word_count == 2)
        {
            iss.str(line);
            iss.clear();
            iss.seekg(0, std::ios::beg); // 将iss重新指向该行行首
            bool isnt_serial = false;
            item_file << 0 << " " << 0;
            while (iss >> word)
            {
                if (isnt_serial)
                {
                    for (int i = 0; i < TERMINAL_SYMBOL_NUM; i++)
                    {
                        if (word == terminal_symbol[i])
                        {
                            item_file << " " << i + 1;
                        }
                    }
                    for (int i = 0; i < NON_TERMINAL_SYMBOL_NUM; i++)
                    {
                        if (word == non_terminal_symbol[i])
                        {
                            item_file << " " << i + TERMINAL_SYMBOL_NUM + 1;
                        }
                    }
                }
                else
                {
                    isnt_serial = true;
                }
            }
            item_file << "\n";
            item_num++;
        }
        else
        {
            for (int i = 0; i < word_count; i++)
            {
                iss.str(line);
                iss.clear();
                iss.seekg(0, std::ios::beg);
                bool isnt_serial = false;
                item_file << i << " " << word_count - 1;
                while (iss >> word)
                {
                    if (isnt_serial)
                    {
                        for (int i = 0; i < TERMINAL_SYMBOL_NUM; i++)
                        {
                            if (word == terminal_symbol[i])
                            {
                                item_file << " " << i + 1;
                            }
                        }
                        for (int i = 0; i < NON_TERMINAL_SYMBOL_NUM; i++)
                        {
                            if (word == non_terminal_symbol[i])
                            {
                                item_file << " " << i + TERMINAL_SYMBOL_NUM + 1;
                            }
                        }
                    }
                    else
                    {
                        isnt_serial = true;
                    }
                }
                item_file << "\n";
                item_num++;
            }
        }
    }
    grammar_file.close();
    item_file.close();
    return item_num;
}

int get_item_family(char *in_file, int item_num, item_info my_item[], vector<vector<int>> &family_member, vector<item_family_edge> &my_edge)
{
    ifstream item_file(in_file);
    ofstream debug_item_file("./debug/debug_item.txt");
    ofstream debug_item_family_file("./debug/debug_item_family.txt");
    if (!item_file.is_open())
    {
        perror("Open item file error!");
    }
    if (!debug_item_file.is_open())
    {
        perror("Create debug item file error!");
    }
    if (!debug_item_family_file.is_open())
    {
        perror("Create debug item family file error!");
    }

    string line;
    int cur_item_ptr = 0;

    // 将item信息存入数组，方便处理
    while (getline(item_file, line) && cur_item_ptr < item_num)
    {
        get_item_info(&my_item[cur_item_ptr], line);
        debug_print_item(my_item[cur_item_ptr], cur_item_ptr, debug_item_file);
        cur_item_ptr++;
    }
    vector<family_info> my_family_info;
    int family_num = 1;
    family_member.resize(family_num);
    family_member[0].push_back(0);
    my_family_info.push_back(family_info(0, 0));

    for (int i = 0; i < family_member[0].size(); i++)
    {
        for (int j = 0; j < item_num; j++)
        {
            if (my_item[j].point_pos == 0 && my_item[j].left == my_item[family_member[0][i]].right[0] && !is_in_family(family_member[0], family_member[0].size(), j))
            {
                family_member[0].push_back(j);
            }
        }
    }
    my_family_info[0].is_expand = 1;
    // 上面将family0初始化完成

    bool *is_branched = new bool[family_member[0].size()];
    int tem_symbol = -1;
    for (int i = 0; i < family_member[0].size(); i++) // 遍历族0的所有项目
    {
        if (my_item[family_member[0][i]].point_pos < my_item[family_member[0][i]].right_num) // 当前项目的点的位置不在最后，即点还可以后移
        {
            if (!is_branched[i]) // 该项目未分支
            {
                tem_symbol = my_item[family_member[0][i]].right[my_item[family_member[0][i]].point_pos];
                family_member.resize(++family_num);
                family_member[family_num - 1].push_back(family_member[0][i] + 1); // 下一项目放入一个新的family
                is_branched[i] = true;
                for (int j = i + 1; j < family_member[0].size(); j++) // 找到与该项目下一字符相同的所有项目，放入同一组
                {
                    if (my_item[family_member[0][j]].point_pos < my_item[family_member[0][j]].right_num && my_item[family_member[0][j]].right[my_item[family_member[0][j]].point_pos] == tem_symbol)
                    {
                        family_member[family_num - 1].push_back(family_member[0][j] + 1);
                        is_branched[j] = true;
                    }
                }
                my_family_info.push_back(family_info(0, 0));
                my_edge.push_back(item_family_edge(0, family_num - 1, my_item[family_member[0][i]].right[my_item[family_member[0][i]].point_pos]));
            }
        }
    }
    free(is_branched);
    my_family_info[0].is_branch = 1;
    bool need_to_while = true;
    int while_num = 0;
    while (need_to_while) // 一直循环，直到不变化
    {
        need_to_while = false;
        for (int i_f = 0; i_f < family_member.size(); i_f++) // 遍历所有集合
        {
            if (!my_family_info[i_f].is_expand) // 该集合未拓展
            {
                for (int i_i = 0; i_i < family_member[i_f].size(); i_i++) // 遍历当前族的所有项目
                {
                    for (int j = 0; j < item_num; j++)
                    {
                        if (!is_in_family(family_member[i_f], family_member[i_f].size(), j) && my_item[j].point_pos == 0 && my_item[family_member[i_f][i_i]].point_pos < my_item[family_member[i_f][i_i]].right_num && my_item[j].left == my_item[family_member[i_f][i_i]].right[my_item[family_member[i_f][i_i]].point_pos])
                        {
                            family_member[i_f].push_back(j);
                        }
                    }
                }
                // 以上将family[i_f]进行拓展
                need_to_while = true;
                my_family_info[i_f].is_expand = 1;
            }
            if (!my_family_info[i_f].is_branch) // 该集合未继续分支
            {
                is_branched = new bool[family_member[i_f].size()];
                for (int i_i = 0; i_i < family_member[i_f].size(); i_i++) // 遍历当前族的所有项目
                {
                    if (my_item[family_member[i_f][i_i]].point_pos < my_item[family_member[i_f][i_i]].right_num) // 当前项目的点的位置不在最后，即点还可以后移
                    {
                        if (!is_branched[i_i])
                        {
                            int index = -1;
                            if ((index = is_in_family_x(family_member, family_member.size(), family_member[i_f][i_i] + 1)) != -1)
                            {
                                tem_symbol = my_item[family_member[i_f][i_i]].right[my_item[family_member[i_f][i_i]].point_pos];
                                my_edge.push_back(item_family_edge(i_f, index, my_item[family_member[i_f][i_i]].right[my_item[family_member[i_f][i_i]].point_pos]));
                                is_branched[i_i] = true;
                                for (int j = i_i + 1; j < family_member[i_f].size(); j++)
                                {
                                    if (my_item[family_member[i_f][j]].point_pos < my_item[family_member[i_f][j]].right_num && my_item[family_member[i_f][j]].right[my_item[family_member[i_f][j]].point_pos] == tem_symbol)
                                    {
                                        is_branched[j] = true;
                                    }
                                }
                            }
                            else
                            {
                                if (!is_branched[i_i])
                                {
                                    tem_symbol = my_item[family_member[i_f][i_i]].right[my_item[family_member[i_f][i_i]].point_pos];
                                    family_member.resize(++family_num);
                                    family_member[family_num - 1].push_back(family_member[i_f][i_i] + 1); // 下一项目放入一个新的family
                                    is_branched[i_i] = true;
                                    for (int j = i_i + 1; j < family_member[i_f].size(); j++)
                                    {
                                        if (my_item[family_member[i_f][j]].point_pos < my_item[family_member[i_f][j]].right_num && my_item[family_member[i_f][j]].right[my_item[family_member[i_f][j]].point_pos] == tem_symbol)
                                        {
                                            family_member[family_num - 1].push_back(family_member[i_f][j] + 1);
                                            is_branched[j] = true;
                                        }
                                    }
                                    my_family_info.push_back(family_info(0, 0));
                                    my_edge.push_back(item_family_edge(i_f, family_num - 1, my_item[family_member[i_f][i_i]].right[my_item[family_member[i_f][i_i]].point_pos]));
                                }
                            }
                        }
                    }
                    // 以上添加边
                }
                need_to_while = true;
                my_family_info[i_f].is_branch = 1;
                free(is_branched);
            }
        }
    }
    debug_print_family(my_item, family_member, 0, 1, debug_item_family_file);
    debug_item_family_file << "\n";
    debug_print_edge(my_edge, 0, 1, debug_item_family_file);

    item_file.close();
    debug_item_file.close();
    debug_item_family_file.close();

    return family_num;
}

int get_state_table(int state_table[][TERMINAL_SYMBOL_NUM + NON_TERMINAL_SYMBOL_NUM + 1], int family_num, item_info my_item[], int item_num, vector<vector<int>> family_member, vector<item_family_edge> my_edge, bool follow[][TERMINAL_SYMBOL_NUM + 1])
{
    int acc_state = -1;
    ofstream debug_table_file("./debug/debug_table.txt");
    if (!debug_table_file.is_open())
    {
        perror("Create debug table file error!");
    }
    for (int i = 0; i < family_num; i++)
    {
        for (int j = 0; j < family_member[i].size(); j++)
        {
            if (my_item[family_member[i][j]].left == 0 && my_item[family_member[i][j]].right_num == 1 && my_item[family_member[i][j]].right[0] == TERMINAL_SYMBOL_NUM + 1 && my_item[family_member[i][j]].point_pos == 1)
            {
                state_table[i][0] = ACC;
                acc_state = i;
            }
        }
    }
    // 上面将包含 myStart -> Program (#) 项的状态遇到#的位置置为ACC

    for (int i = 0; i < family_num; i++) // 遍历状态，即状态表的列
    {
        if (i == acc_state)
        {
            continue;
        }
        for (int j = 0; j < family_member[i].size(); j++) // 当前状态第j项
        {
            for (int k = 0; k < TERMINAL_SYMBOL_NUM + NON_TERMINAL_SYMBOL_NUM + 1; k++)
            {
                if (my_item[family_member[i][j]].point_pos < my_item[family_member[i][j]].right_num)
                {
                    for (int e = 0; e < my_edge.size(); e++) // 遍历边
                    {
                        if (my_edge[e].from == i && my_edge[e].symbol == k)
                        {
                            state_table[i][k] = my_edge[e].to;
                        }
                    }
                }
                else if (state_table[i][k] == INIT && my_item[family_member[i][j]].point_pos == my_item[family_member[i][j]].right_num &&k <=TERMINAL_SYMBOL_NUM && follow[my_item[family_member[i][j]].left - TERMINAL_SYMBOL_NUM - 1][k])
                {
                    state_table[i][k] = family_num + family_member[i][j];
                }
                
            }
        }
    }

    debug_table_file << "\t";
    for (int i = 0; i < TERMINAL_SYMBOL_NUM + NON_TERMINAL_SYMBOL_NUM + 1; i++)
    {
        debug_table_file << i << "\t";
    }
    debug_table_file << "\n";
    for (int i = 0; i < family_num; i++)
    {
        debug_table_file << i << "\t";
        for (int j = 0; j < TERMINAL_SYMBOL_NUM + NON_TERMINAL_SYMBOL_NUM + 1; j++)
        {
            debug_table_file << state_table[i][j] << "\t";
        }
        debug_table_file << "\n";
    }

    debug_table_file.close();
    return acc_state;
}

int syntax_analyze(char *lex_file_path, int state_table[][TERMINAL_SYMBOL_NUM + NON_TERMINAL_SYMBOL_NUM + 1], int family_num, item_info my_item[], int acc_state)
{
    ifstream lex_file(lex_file_path);
    ofstream out_file("./inter_txt/syn_analyzed.txt");
    ofstream debug_syntax_file("./debug/debug_syntax_analyze.txt");
    if (!lex_file.is_open())
    {
        perror("Open lex file error!");
    }
    if (!out_file.is_open())
    {
        perror("Create final file error!");
    }
    if (!debug_syntax_file.is_open())
    {
        perror("Create debug syntax file error!");
    }

    Stack state_stack = Stack(false); // 状态栈
    Stack symbol_stack = Stack(true); // 符号栈
    state_stack.push(0);              // 压入0
    symbol_stack.push(0);             // 压入#
    string line;
    string word1;
    string word2;
    int cur_symbol = 0;
    int symbol_case = 0;
    bool is_reduct = false;
    int step = 1;
    while (1)
    {
        if (!is_reduct)
        {
            getline(lex_file, line);
            istringstream iss(line);
            iss >> word1 >> word2;
        }
        else
        {
            is_reduct = false;
        }
        out_file << step++ << "\t";
        if(!symbol_stack.top())
        {
            out_file << "#";
        }
        else if(symbol_stack.top() > 0 && symbol_stack.top() < TERMINAL_SYMBOL_NUM+1)
        {
            out_file << terminal_symbol[symbol_stack.top()-1];
        }
        else
        {
            out_file << non_terminal_symbol[symbol_stack.top()-TERMINAL_SYMBOL_NUM-1];
        }
        out_file<<"#"<< word1 << "\t";
        debug_print_syntax_analyze(&state_stack, &symbol_stack, word1, debug_syntax_file);
        if (((cur_symbol = find_in_symbol(word1)) != 0 && (word2.find("KW") != std::string::npos || word2.find("OP") != std::string::npos || word2.find("SE") != std::string::npos) && (symbol_case = cur_symbol)) || (word2.find("INT") != std::string::npos && (symbol_case = find_in_symbol("INT"))) || (word2.find("FLOAT") != std::string::npos && (symbol_case = find_in_symbol("FLOAT"))) || ((word2.find("IDN") != std::string::npos || word1 == "main") && (symbol_case = find_in_symbol("IDN"))) || (word1 == "#"))
        {
            if(word1 == "#")
            {
                symbol_case = 0;
            }
            if (state_table[state_stack.top()][symbol_case] < family_num && state_table[state_stack.top()][symbol_case] > 0) // table里是转移状态操作
            {
                out_file << "move";
                debug_syntax_file << "move";
                state_stack.push(state_table[state_stack.top()][symbol_case]); // 将下一状态移进状态栈
                symbol_stack.push(symbol_case);
            }
            else if (state_table[state_stack.top()][symbol_case] >= family_num) // 是归约操作
            {
                out_file << "reduction";
                debug_syntax_file << "reduction";
                symbol_stack.reduct(my_item[state_table[state_stack.top()][symbol_case] - family_num]);
                state_stack.reduct(my_item[state_table[state_stack.top()][symbol_case] - family_num]);
                state_stack.push(state_table[state_stack.top()][symbol_stack.top()]);
                is_reduct = true;
            }
            else if (word1 == "#" && state_stack.top() == acc_state)
            {
                out_file << "accept";
                debug_syntax_file << "accept";
                break;
            }
            else
            {
                out_file <<  ("error\n");
                debug_syntax_file << ("Error! Unexpected symbol.\n");
                return EXIT_FAILURE;
            }
            out_file << "\n";
            debug_syntax_file << "\n";
        }
        else
        {
            out_file << "error\n";
            debug_syntax_file << "Error! Symbol not found.\n";
            return EXIT_FAILURE;
        }
    }
    lex_file.close();
    out_file.close();
    debug_syntax_file.close();
    return EXIT_SUCCESS;
}
